home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / system / source / w32assist.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-07-14  |  11.3 KB  |  400 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #include "stdafx.h"
  27. #include <vd2/system/w32assist.h>
  28. #include <vd2/system/text.h>
  29. #include <vd2/system/vdstl.h>
  30.  
  31. bool VDIsForegroundTaskW32() {
  32.     HWND hwndFore = GetForegroundWindow();
  33.  
  34.     if (!hwndFore)
  35.         return false;
  36.  
  37.     DWORD dwProcessId = 0;
  38.     GetWindowThreadProcessId(hwndFore, &dwProcessId);
  39.  
  40.     return dwProcessId == GetCurrentProcessId();
  41. }
  42.  
  43. LPVOID VDConvertThreadToFiberW32(LPVOID parm) {
  44.     typedef LPVOID (WINAPI *tpConvertThreadToFiber)(LPVOID p);
  45.     static tpConvertThreadToFiber ctof = (tpConvertThreadToFiber)GetProcAddress(GetModuleHandle("kernel32"), "ConvertThreadToFiber");
  46.  
  47.     if (!ctof)
  48.         return NULL;
  49.  
  50.     return ctof(parm);
  51. }
  52.  
  53. void VDSwitchToFiberW32(LPVOID fiber) {
  54.     typedef void (WINAPI *tpSwitchToFiber)(LPVOID p);
  55.     static tpSwitchToFiber stof = (tpSwitchToFiber)GetProcAddress(GetModuleHandle("kernel32"), "SwitchToFiber");
  56.  
  57.     if (stof)
  58.         stof(fiber);
  59. }
  60.  
  61. int VDGetSizeOfBitmapHeaderW32(const BITMAPINFOHEADER *pHdr) {
  62.     int palents = 0;
  63.  
  64.     if ((pHdr->biCompression == BI_RGB || pHdr->biCompression == BI_RLE4 || pHdr->biCompression == BI_RLE8) && pHdr->biBitCount <= 8) {
  65.         palents = pHdr->biClrUsed;
  66.         if (!palents)
  67.             palents = 1 << pHdr->biBitCount;
  68.     }
  69.     int size = pHdr->biSize + palents * sizeof(RGBQUAD);
  70.  
  71.     if (pHdr->biSize < sizeof(BITMAPV4HEADER) && pHdr->biCompression == BI_BITFIELDS)
  72.         size += sizeof(DWORD) * 3;
  73.  
  74.     return size;
  75. }
  76.  
  77. void VDSetWindowTextW32(HWND hwnd, const wchar_t *s) {
  78.     if (VDIsWindowsNT()) {
  79.         SetWindowTextW(hwnd, s);
  80.     } else {
  81.         SetWindowTextA(hwnd, VDTextWToA(s).c_str());
  82.     }
  83. }
  84.  
  85. VDStringW VDGetWindowTextW32(HWND hwnd) {
  86.     union {
  87.         wchar_t w[256];
  88.         char a[512];
  89.     } buf;
  90.  
  91.     if (VDIsWindowsNT()) {
  92.         int len = GetWindowTextLengthW(hwnd);
  93.  
  94.         if (len > 255) {
  95.             vdblock<wchar_t> tmp(len + 1);
  96.             len = GetWindowTextW(hwnd, tmp.data(), tmp.size());
  97.  
  98.             VDStringW text(tmp.data(), len);
  99.             return text;
  100.         } else if (len > 0) {
  101.             len = GetWindowTextW(hwnd, buf.w, 256);
  102.  
  103.             VDStringW text(buf.w, len);
  104.             return text;
  105.         }
  106.     } else {
  107.         int len = GetWindowTextLengthA(hwnd);
  108.  
  109.         if (len > 511) {
  110.             vdblock<char> tmp(len + 1);
  111.             len = GetWindowTextA(hwnd, tmp.data(), tmp.size());
  112.  
  113.             VDStringW text(VDTextAToW(tmp.data(), len));
  114.             return text;
  115.         } else if (len > 0) {
  116.             len = GetWindowTextA(hwnd, buf.a, 512);
  117.  
  118.             VDStringW text(VDTextAToW(buf.a, len));
  119.             return text;
  120.         }
  121.     }
  122.  
  123.     return VDStringW();
  124. }
  125.  
  126. void VDAppendMenuW32(HMENU hmenu, UINT flags, UINT id, const wchar_t *text){
  127.     if (VDIsWindowsNT()) {
  128.         AppendMenuW(hmenu, flags, id, text);
  129.     } else {
  130.         AppendMenuA(hmenu, flags, id, VDTextWToA(text).c_str());
  131.     }
  132. }
  133.  
  134. void VDCheckMenuItemByCommandW32(HMENU hmenu, UINT cmd, bool checked) {
  135.     CheckMenuItem(hmenu, cmd, checked ? MF_BYCOMMAND|MF_CHECKED : MF_BYCOMMAND|MF_UNCHECKED);
  136. }
  137.  
  138. void VDCheckRadioMenuItemByCommandW32(HMENU hmenu, UINT cmd, bool checked) {
  139.     MENUITEMINFOA mii;
  140.  
  141.     mii.cbSize = sizeof(MENUITEMINFOA);
  142.     mii.fMask = MIIM_FTYPE | MIIM_STATE;
  143.     if (GetMenuItemInfo(hmenu, cmd, FALSE, &mii)) {
  144.         mii.fType |= MFT_RADIOCHECK;
  145.         mii.fState &= ~MFS_CHECKED;
  146.         if (checked)
  147.             mii.fState |= MFS_CHECKED;
  148.         SetMenuItemInfo(hmenu, cmd, FALSE, &mii);
  149.     }
  150. }
  151.  
  152. void VDEnableMenuItemByCommandW32(HMENU hmenu, UINT cmd, bool checked) {
  153.     EnableMenuItem(hmenu, cmd, checked ? MF_BYCOMMAND|MF_ENABLED : MF_BYCOMMAND|MF_GRAYED);
  154. }
  155.  
  156. void VDSetMenuItemTextByCommandW32(HMENU hmenu, UINT cmd, const wchar_t *text) {
  157.     if (VDIsWindowsNT()) {
  158.         MENUITEMINFOW mmiW;
  159.  
  160.         mmiW.cbSize        = MENUITEMINFO_SIZE_VERSION_400W;
  161.         mmiW.fMask        = MIIM_TYPE;
  162.         mmiW.fType        = MFT_STRING;
  163.         mmiW.dwTypeData    = (LPWSTR)text;
  164.  
  165.         SetMenuItemInfoW(hmenu, cmd, FALSE, &mmiW);
  166.     } else {
  167.         MENUITEMINFOA mmiA;
  168.         VDStringA textA(VDTextWToA(text));
  169.  
  170.         mmiA.cbSize        = MENUITEMINFO_SIZE_VERSION_400A;
  171.         mmiA.fMask        = MIIM_TYPE;
  172.         mmiA.fType        = MFT_STRING;
  173.         mmiA.dwTypeData    = (LPSTR)textA.c_str();
  174.  
  175.         SetMenuItemInfoA(hmenu, cmd, FALSE, &mmiA);
  176.     }
  177. }
  178.  
  179. LRESULT    VDDualCallWindowProcW32(WNDPROC wp, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  180.     return (IsWindowUnicode(hwnd) ? CallWindowProcW : CallWindowProcA)(wp, hwnd, msg, wParam, lParam);
  181. }
  182.  
  183. LRESULT VDDualDefWindowProcW32(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  184.     return IsWindowUnicode(hwnd) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam);
  185. }
  186.  
  187. EXECUTION_STATE VDSetThreadExecutionStateW32(EXECUTION_STATE esFlags) {
  188.     EXECUTION_STATE es = 0;
  189.  
  190.     // SetThreadExecutionState(): requires Windows 98+/2000+.
  191.     typedef EXECUTION_STATE (WINAPI *tSetThreadExecutionState)(EXECUTION_STATE);
  192.     static tSetThreadExecutionState pFunc = (tSetThreadExecutionState)GetProcAddress(GetModuleHandle("kernel32"), "SetThreadExecutionState");
  193.  
  194.     if (pFunc)
  195.         es = pFunc(esFlags);
  196.  
  197.     return es;
  198. }
  199.  
  200. bool VDSetFilePointerW32(HANDLE h, sint64 pos, DWORD dwMoveMethod) {
  201.     LONG posHi = (LONG)(pos >> 32);
  202.     DWORD result = SetFilePointer(h, (LONG)pos, &posHi, dwMoveMethod);
  203.  
  204.     if (result != INVALID_SET_FILE_POINTER)
  205.         return true;
  206.  
  207.     DWORD dwError = GetLastError();
  208.  
  209.     return (dwError == NO_ERROR);
  210. }
  211.  
  212. bool VDGetFileSizeW32(HANDLE h, sint64& size) {
  213.     DWORD dwSizeHigh;
  214.     DWORD dwSizeLow = GetFileSize(h, &dwSizeHigh);
  215.  
  216.     if (dwSizeLow == (DWORD)-1 && GetLastError() != NO_ERROR)
  217.         return false;
  218.  
  219.     size = dwSizeLow + ((sint64)dwSizeHigh << 32);
  220.     return true;
  221. }
  222.  
  223. #if !defined(_MSC_VER) || _MSC_VER < 1300
  224. HMODULE VDGetLocalModuleHandleW32() {
  225.     MEMORY_BASIC_INFORMATION meminfo;
  226.     static HMODULE shmod = (VirtualQuery(&VDGetLocalModuleHandleW32, &meminfo, sizeof meminfo), (HMODULE)meminfo.AllocationBase);
  227.  
  228.     return shmod;
  229. }
  230. #endif
  231.  
  232. bool VDDrawTextW32(HDC hdc, const wchar_t *s, int nCount, LPRECT lpRect, UINT uFormat) {
  233.     RECT r;
  234.     if (VDIsWindowsNT()) {
  235.         // If multiline and vcentered (not normally supported...)
  236.         if (!((uFormat ^ DT_VCENTER) & (DT_VCENTER|DT_SINGLELINE))) {
  237.             uFormat &= ~DT_VCENTER;
  238.  
  239.             r = *lpRect;
  240.             if (!DrawTextW(hdc, s, nCount, &r, uFormat | DT_CALCRECT))
  241.                 return false;
  242.  
  243.             int dx = ((lpRect->right - lpRect->left) - (r.right - r.left)) >> 1;
  244.             int dy = ((lpRect->bottom - lpRect->top) - (r.bottom - r.top)) >> 1;
  245.  
  246.             r.left += dx;
  247.             r.right += dx;
  248.             r.top += dy;
  249.             r.bottom += dy;
  250.             lpRect = &r;
  251.         }
  252.  
  253.         return !!DrawTextW(hdc, s, nCount, lpRect, uFormat);
  254.     } else {
  255.         VDStringA strA(VDTextWToA(s, nCount));
  256.  
  257.         // If multiline and vcentered (not normally supported...)
  258.         if (!((uFormat ^ DT_VCENTER) & (DT_VCENTER|DT_SINGLELINE))) {
  259.             uFormat &= ~DT_VCENTER;
  260.  
  261.             r = *lpRect;
  262.             if (!DrawTextA(hdc, strA.data(), strA.size(), &r, uFormat | DT_CALCRECT))
  263.                 return false;
  264.  
  265.             int dx = ((lpRect->right - lpRect->left) - (r.right - r.left)) >> 1;
  266.             int dy = ((lpRect->bottom - lpRect->top) - (r.bottom - r.top)) >> 1;
  267.  
  268.             r.left += dx;
  269.             r.right += dx;
  270.             r.top += dy;
  271.             r.bottom += dy;
  272.             lpRect = &r;
  273.         }
  274.  
  275.         return !!DrawTextA(hdc, strA.data(), strA.size(), lpRect, uFormat);
  276.     }
  277. }
  278.  
  279. bool VDPatchModuleImportTableW32(HMODULE hmod, const char *srcModule, const char *name, void *pCompareValue, void *pNewValue, void *volatile *ppOldValue) {
  280.     char *pBase = (char *)hmod;
  281.  
  282.     __try {
  283.         // The PEheader offset is at hmod+0x3c.  Add the size of the optional header
  284.         // to step to the section headers.
  285.  
  286.         const uint32 peoffset = ((const long *)pBase)[15];
  287.         const uint32 signature = *(uint32 *)(pBase + peoffset);
  288.  
  289.         if (signature != IMAGE_NT_SIGNATURE)
  290.             return false;
  291.  
  292.         const IMAGE_FILE_HEADER *pHeader = (const IMAGE_FILE_HEADER *)(pBase + peoffset + 4);
  293.  
  294.         // Verify the PE optional structure.
  295.  
  296.         if (pHeader->SizeOfOptionalHeader < 104)
  297.             return false;
  298.  
  299.         // Find import header.
  300.  
  301.         const IMAGE_IMPORT_DESCRIPTOR *pImportDir;
  302.         int nImports;
  303.  
  304.         switch(*(short *)((char *)pHeader + IMAGE_SIZEOF_FILE_HEADER)) {
  305.  
  306. #ifdef _M_AMD64
  307.         case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
  308.             {
  309.                 const IMAGE_OPTIONAL_HEADER64 *pOpt = (IMAGE_OPTIONAL_HEADER64 *)((const char *)pHeader + sizeof(IMAGE_FILE_HEADER));
  310.  
  311.                 if (pOpt->NumberOfRvaAndSizes < 2)
  312.                     return false;
  313.  
  314.                 pImportDir = (const IMAGE_IMPORT_DESCRIPTOR *)(pBase + pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  315.                 nImports = pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
  316.             }
  317.             break;
  318. #else
  319.         case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
  320.             {
  321.                 const IMAGE_OPTIONAL_HEADER32 *pOpt = (IMAGE_OPTIONAL_HEADER32 *)((const char *)pHeader + sizeof(IMAGE_FILE_HEADER));
  322.  
  323.                 if (pOpt->NumberOfRvaAndSizes < 2)
  324.                     return false;
  325.  
  326.                 pImportDir = (const IMAGE_IMPORT_DESCRIPTOR *)(pBase + pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  327.                 nImports = pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
  328.             }
  329.             break;
  330. #endif
  331.  
  332.         default:        // reject PE32+
  333.             return false;
  334.         }
  335.  
  336.         // Hmmm... no imports?
  337.  
  338.         if ((const char *)pImportDir == pBase)
  339.             return false;
  340.  
  341.         // Scan down the import entries.  We are looking for MSVFW32.
  342.  
  343.         int i;
  344.  
  345.         for(i=0; i<nImports; ++i) {
  346.             if (!_stricmp(pBase + pImportDir[i].Name, srcModule))
  347.                 break;
  348.         }
  349.  
  350.         if (i >= nImports)
  351.             return false;
  352.  
  353.         // Found it.  Start scanning MSVFW32 imports until we find DrawDibDraw.
  354.  
  355.         const long *pImports = (const long *)(pBase + pImportDir[i].OriginalFirstThunk);
  356.         void * volatile *pVector = (void * volatile *)(pBase + pImportDir[i].FirstThunk);
  357.  
  358.         while(*pImports) {
  359.             if (*pImports >= 0) {
  360.                 const char *pName = pBase + *pImports + 2;
  361.  
  362.                 if (!strcmp(pName, name)) {
  363.  
  364.                     // Found it!  Reset the protection.
  365.  
  366.                     DWORD dwOldProtect;
  367.  
  368.                     if (VirtualProtect((void *)pVector, sizeof(void *), PAGE_EXECUTE_READWRITE, &dwOldProtect)) {
  369.                         if (ppOldValue) {
  370.                             for(;;) {
  371.                                 void *old = *pVector;
  372.                                 if (pCompareValue && pCompareValue != old)
  373.                                     return false;
  374.  
  375.                                 *ppOldValue = old;
  376.                                 if (old == VDAtomicCompareExchangePointer(pVector, pNewValue, old))
  377.                                     break;
  378.                             }
  379.                         } else {
  380.                             *pVector = pNewValue;
  381.                         }
  382.  
  383.                         VirtualProtect((void *)pVector, sizeof(void *), dwOldProtect, &dwOldProtect);
  384.  
  385.                         return true;
  386.                     }
  387.  
  388.                     break;
  389.                 }
  390.             }
  391.  
  392.             ++pImports;
  393.             ++pVector;
  394.         }
  395.     } __except(1) {
  396.     }
  397.  
  398.     return false;
  399. }
  400.